package colibri.lcdui;

import colibri.App;
import java.io.InputStream;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 *
 * @author Bayron Thiengo Quinelato
 */
class TouchKeyboard extends Item {

    private int iconWidth, iconHieght;
    private int bufferX, bufferY;
    private int _width;
    public boolean isOpen;
    private boolean isPressedIcon;
    private boolean isPressed;
    private Image imOut, imIn;
    private Image imIconOut, imIconIn;
    private Image imBuffer;
    private int[][] keyInfo;
    private int exitKeyIndex;
    private String filePath;
    private TextField textField;
    // Caracters especiais
    private static final char[] CHARS = new char[]{'.', ',', '?', '!', '@', 
        '\'', '-', '_', '(', ')', ':', ';', '&', '\\', '/', '%', '*', '#', '+',
        '<', '=', '>', '\"', '$'};
    private int currentKeyStep;
    private int lastPressedKey;
    private boolean goToNextChar = false;
    private long lastKeyTimeStamp = 0;
    private long maxKeyDelay = 500L;

    public TouchKeyboard() {
        super(App.halfWidth, 0, App.width, 0, Graphics.TOP | Graphics.LEFT);
        try {
            imIconOut = Image.createImage("/res/img/keyboard_icon_out.png");
            imIconIn = Image.createImage("/res/img/keyboard_icon_in.png");
        } catch (Exception e) {
            e.printStackTrace();
            throw new NullPointerException("Colibri error: Falha na criação do teclado touch screen. Não foi possível carregar as imagens do teclado.");
        }
        iconWidth = imIconOut.getWidth();
        iconHieght = imIconOut.getHeight();
        width = iconWidth;
        height = iconHieght;
        x = (App.width - width) / 2;
        y = App.height - height;
    }

    private void configureTouchKey() {
        _width = App.width;
        filePath = "/res/keyboard/";
        if (App.width >= 320) {
            filePath += "320_or_more";
        } else if (App.width >= 240) {
            filePath += "240";
        } else {
            filePath += "176";
        }
        try {
            imOut = Image.createImage(filePath + "_out.png");
            imIn = Image.createImage(filePath + "_in.png");
        } catch (Exception e) {
            e.printStackTrace();
            throw new NullPointerException("Colibri error: Falha na criação do teclado touch screen. Não foi possível carregar as imagens do teclado.");
        }
        width = imOut.getWidth();
        height = imOut.getHeight();
        x = (App.width - width) / 2;
        y = App.height - height;
        loadKeyInfo();
    }

    private void loadKeyInfo() {
        keyInfo = new int[41][5];
        exitKeyIndex = keyInfo.length - 1;
        int c = 0;
        int contVirgula = 0;
        int cont = 0;
        int adjustmentX = 0;
        if (App.width > 320) {
            adjustmentX = App.width - 320;
        }
        InputStream is = getClass().getResourceAsStream(filePath + ".kmp");
        StringBuffer sb = new StringBuffer();
        try {
            while ((c = is.read()) != -1) {
                if ((char) c == ',') {
                    if (contVirgula == 0) {
                        keyInfo[cont][contVirgula] = adjustmentX + Integer.parseInt(sb.toString());
                    } else {
                        keyInfo[cont][contVirgula] = Integer.parseInt(sb.toString());
                    }
                    sb = new StringBuffer();
                    contVirgula++;
                } else if ((char) c == '\n' && sb.length() > 0) {
                    keyInfo[cont][contVirgula] = Integer.parseInt(sb.toString());
                    sb = new StringBuffer();
                    cont++;
                    contVirgula = 0;
                } else if (c != 10 && c != 13) {
                    sb.append((char) c);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new NullPointerException("Colibri error: Falha na criação do teclado touch screen. Não foi possível carregar as configurações do teclado.");
        }
    }

    protected void callPaint(Graphics g) {
        if (isOpen) {
            if (_width != App.width) {
                configureTouchKey();
                return;
            }
            if (textField != null) {
                g.drawImage(imOut, App.halfWidth, App.height, Graphics.BOTTOM | Graphics.HCENTER);
                if (isPressed) {
                    g.drawImage(imBuffer, bufferX, bufferY, Graphics.TOP | Graphics.LEFT);
                }
                //Desenha o campo de entrada de texto acima do teclado touch screen.
                textField.callPaint(g);
            }
        } else  {
            if (isPressedIcon) {
                g.drawImage(imIconIn, App.halfWidth, App.height - 1, Graphics.BOTTOM | Graphics.HCENTER);
            } else {
                g.drawImage(imIconOut, App.halfWidth, App.height - 1, Graphics.BOTTOM | Graphics.HCENTER);
            }
        }
    }

    protected void callKeyReleased(int keyCode) {
        if (isOpen && textField != null) {
            textField.callKeyReleased(keyCode);
        }
    }

    protected void callKeyRepeated(int keyCode) {
        if (isOpen && textField != null) {
            textField.callKeyRepeated(keyCode);
        }
    }

    protected void callPointerPressed(int x, int y) {
        isPressed = false;
        if (!isOpen && x > App.halfWidth - iconWidth && x < App.halfWidth + iconWidth
                && y > App.height - iconHieght - 5) {
            isPressedIcon = true;
        } else if (isOpen && textField != null) {
            if (x > this.x && x < this.x + this.width && y > this.y && y < this.y + this.height) {
                int tkY = this.y + textField.height;
                for (int l = 0; l < keyInfo.length; l++) {
                    if (x > this.x + keyInfo[l][0] && x < this.x + keyInfo[l][0] + keyInfo[l][2]
                            && y > tkY + keyInfo[l][1] && y < tkY + keyInfo[l][1] + keyInfo[l][3]) {
                        isPressed = true;
                        bufferX = this.x + keyInfo[l][0];
                        bufferY = tkY + keyInfo[l][1];
                        try {
                            imBuffer = Image.createImage(imIn, keyInfo[l][0], keyInfo[l][1], keyInfo[l][2], keyInfo[l][3], 0);
                        } catch (Exception e) {
                            e.printStackTrace();
                            throw new NullPointerException("Colibri error: Falha na criação do teclado touch screen. Não foi possível carregar as imagens do teclado.");
                        }
                    }
                }
            }
        }
    }

    protected void callPointerReleased(int x, int y) {
        isPressed = false;
        if (isPressedIcon) {
            isPressedIcon = false;
        }
        if (!isOpen && x > App.halfWidth - iconWidth && x < App.halfWidth + iconWidth
                && y > App.height - iconHieght - 5) {
            if (textField != null) {
                isOpen = true;
                textField.setVisible(true);
                textField.focus = true;
            }

        } else if (isOpen && x > this.x + keyInfo[exitKeyIndex][0]
                && x < this.x + keyInfo[exitKeyIndex][0] + keyInfo[exitKeyIndex][2]
                && y > this.y + textField.height + keyInfo[exitKeyIndex][1]
                && y < this.y + textField.height + keyInfo[exitKeyIndex][1] + keyInfo[exitKeyIndex][3]) {
            isOpen = false;
            textField.setVisible(false);
            textField.focus = false;
            
        } else if (isOpen && textField != null) {
            if (x > this.x && x < this.x + this.width && y > this.y && y < this.y + this.height) {
                int tkY = this.y + textField.height;
                for (int l = 0; l < keyInfo.length - 1; l++) {
                    if (x > this.x + keyInfo[l][0] && x < this.x + keyInfo[l][0] + keyInfo[l][2]
                            && y > tkY + keyInfo[l][1] && y < tkY + keyInfo[l][1] + keyInfo[l][3]) {
                        // Escreve os caracteres especiais
                        if (keyInfo[l][4] == -1 
                                && (textField.getConstrains() == TextField.ANY
                                || textField.getConstrains() == TextField.ANY_PASSWORD)) {
                            if (keyInfo[l][4] != lastPressedKey) {
                                goToNextChar = true;
                                currentKeyStep = 0;
                            } else {
                                if (!goToNextChar && lastKeyTimeStamp + maxKeyDelay < System.currentTimeMillis()) {
                                    goToNextChar = true;
                                }
                                if (!goToNextChar && currentKeyStep < CHARS.length - 1)
                                    currentKeyStep++;
                                else
                                    currentKeyStep = 0;
                            }
                            StringBuffer temp = new StringBuffer(textField.getText());
                            if (!goToNextChar) {
                                temp.delete(temp.length() - 1, temp.length());
                            }
                            temp.append(CHARS[currentKeyStep]);
                            textField.setText(temp.toString());
                            goToNextChar = false;
                        // Escreve os caracteres normais do alfabeto
                        } else {
                            textField.callKeyReleased(keyInfo[l][4]);
                        }
                        lastPressedKey = keyInfo[l][4];
                    }
                }
            }
            lastKeyTimeStamp = System.currentTimeMillis();
        }
    }

    protected void callPointerDragged(int x, int y) {
        if (isPressedIcon)
            isPressedIcon = false;
    }

    public void setTextField(TextField textField) {
        if (textField == null) {
            this.textField = null;
            height = iconHieght;
            y = App.height - height;
            return;
        }
        configureTouchKey();
        this.textField = new TextField(null, x, y, textField.getMaxChar(), textField.getConstrains());
        this.textField.setType(TextField.TYPE_QWERTY);
        this.textField.setWidth(width);
        this.textField.setText(textField.getText());
        this.textField.setCanvas(textField.getCanvas());
        height = imOut.getHeight() + this.textField.height;
        y = App.height - height;
        this.textField.setPosition(x, y);
    }

    public String getText() {
        if (textField == null) {
            return "";
        }
        return textField.getText();
    }

    public void setText(String text) {
        if (textField != null)
            textField.setText(text);
    }
}
